package network;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

/**
 * Creared with IntelliJ IDEA.
 * Description:udp客户端
 * User:yxd
 * Date:2022-04-11
 * Time:14:55
 */
/*
站在客户端的角度上:五元组
源IP:本机IP
源端口:系统分配的端口
目的IP:服务器的IP
目的端口:服务器的端口
协议类型:UDP
 */
//只有服务器还不行,还得来个客户端,才能真正实现
public class UDPEchoClient {
    private DatagramSocket socket = null;
    private String severIP;//IP地址
    private int severPort;//端口号
    //构造函数
    public UDPEchoClient(String ip,int port) throws SocketException {
        socket = new DatagramSocket();
        //这里就是用无参版本的构造socket对象,就是让系统随机分配一个端口号
        //通常对于服务器而言,端口号都是要自己指定的,因为客户端候选是要根据这个端口号来访问服务器的,如果是让系统分配的话,客户端就不知道服务器的端口号是啥,就无法访问
        //而对于客户端而言,如果手动指定也行,但是系统分配更好一些,因为一个进程中不能有两个相同的端口号,而对于每一个人的客户端,并无法知道这个客户端上面都有哪些端口号被占用了,因此而言让系统分配更好一些
        //由于客户端是主动发起请求的一方,客户端需要在发送请求之前,先知道服务器的端口号和地址,但是反过来在发送请求过去之后,服务器并不需要知道客户端的IP地址和端口号,因此这里系统分配会更好一些,服务器都是程序员自己分配的端口号基本都知道有哪些被占用了,因此可以避免重复
        severIP = ip;//这个指定的是服务器的IP地址和端口号和客户端没有关系
        severPort = port;
    }
    Scanner input = new Scanner(System.in);
    public void start() throws IOException {
        while(true){
            //首先先从控制台读取到用户输入的信息,然后才能发送
            System.out.print("->");
            String request = input.next();
            //然后把用户写的信息构造成一个UDP请求,才能发送
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(severIP),severPort);//这里需要指定发送给谁也就是指定服务器的IP地址和端口号
            //然后发送UDP数据报
            socket.send(requestPacket);

            //发送完之后需要再接收从服务器得到的响应数据
            DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);
            socket.receive(responsePacket);

            //然后再把响应的数据写成字符串形式,然后打印到控制台
            String response = new String(responsePacket.getData(),0,responsePacket.getLength(),"UTF-8");
            System.out.printf("req:%s,resp:%s\n",request,response);
        }


    }

    public static void main(String[] args) throws IOException {
        UDPEchoClient udpEchoClient = new UDPEchoClient("127.0.0.1",9090);
        udpEchoClient.start();
    }
}
